export { }
/**
 * 类型保护
 * 通过一些关键字 typeof  instanceof  for in 来缩小范围
 */
function add(input: string | number) {
  if (typeof input === 'string') {

  } else if (typeof input === 'number') {

  }
}
class Animal {

}
class Bird extends Animal {

}
class Dog extends Animal {

}
function getName(name: Animal) {
  if (name instanceof Dog) {
    console.log(name)
  } else if (name instanceof Bird) {
    console.log(name);
  }
}

// null 保护
function getFirstLetter(s: string | null) {
  // 方式一
  // if (s === null) {
  //   return ''
  // }
  // return s.charAt(0) // 当 strictNullChecks 为true时 不通过
  // 方式二
  // return s = s || ''
  // 方式三
  // return s!.charAt(0)
  // 方式四
  return s?.charAt(0)

}
getFirstLetter(null)
getFirstLetter('123')

// 可辨识的联合类型
interface WarningButton {
  class: 'warning',
  text: '修改'
}
interface DangerButton {
  class: 'danger',
  text: '删除'
}
type Button = WarningButton | DangerButton
// 通过变量不同取值来辨识
function getButton(button: Button) {
  if (button.class === 'warning') {
    console.log(button); // button: WarningButton
  }
  if (button.class === 'danger') {
    console.log(button); // button: DangerButton
  }
}
interface User {
  username: string
}
type Action = {
  type: 'add',
  payload: User
} | {
  type: 'delete',
  payload: number
}
const reducer = (action: Action) => {
  switch (action.type) {
    case 'add':
      action.payload.username
      break;
    case 'delete':
      action.payload
      break;
    default:
      break;
  }
}

interface Bird {
  swing: number
}
interface Dog {
  leg: number
}
function getNumber(x: Bird | Dog) {
  if ('swing' in x) {
    console.log(x);
  }
  if ('leg' in x) {
    console.log(x);
  }
}

// 自定义类型保护
namespace a {
  interface Bird {
    leg: number
  }
  interface Dog {
    leg: number
  }
  // 语法  类型谓词 parameterName is Type
  // function isType(type: Type1 | Type2):type is Type1 {
  // }
  // 示例
  function isBird(x: Bird | Dog): x is Bird {
    return x.leg === 2
  }

  function getAnimal(x: Bird | Dog) {
    if (isBird(x)) {
      console.log(x);
    } else {
      console.log(x);
    }
  }
}

// unknown 是any的安全类型
// any是任意类型 可以对any类型的数据做任何操作 不需要做类型检查
let value: any
value = 1
value = ''
value = true
value = []
value = {}
value.length
value.methods()

let value2: unknown
value2 = ''
value2 = 2
value2 = []
value2 = {}
value2 = true
// 安全类型可以赋值 但不能调用属性或方法
// 错误 value2.methods()
// 错误 value2.length

// 类型断言
value2 = 'smd';
(value2 as string).toLowerCase()
// typeof检查
if (typeof value2 === 'string') {
  value2.toLowerCase()
}

// 联合类型中的unknown   unknown 与任何类型联合  得到的类型都是unknown
type U1 = unknown | null

// 交叉类型
interface A {
  name: string
}
interface B {
  age: number
}
type C = A & B // 交叉类型之后 C类型应该既可以满足A 又可以满足B
let c: C = {
  name: '134',
  age: 20
}

type AA = string | number
type BB = string | boolean
type CC = AA & BB // 交叉类型之后  CC 只能是string
let cc: CC = '123'

// never是unknown的子类型
type isNever = never extends unknown ? true : false // true
type keys = keyof never // string | number | symbol

// unknown类型只能判断是否相等  不能做运算
let aa: unknown
let bb: unknown
if (aa === bb) { }
if (aa !== bb) { }
// 错误 aa+bb
// 错误 aa-bb

// 映射属性
type getType<T> = {
  [P in keyof T]: number // keyof遍历T 拿到所有的类型   P在不在其中
}
type t = getType<unknown> // {}